package top.went.service;

import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.went.db.dao.PurDetailDao;
import top.went.db.dao.PurchaseDao;
import top.went.db.dao.UserDao;
import top.went.db.mapper.PurchaseMapper;
import top.went.exception.NotFoundException;
import top.went.exception.ServiceException;
import top.went.pojo.*;
import top.went.vo.*;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional(value = "transactionManager",rollbackFor = ServiceException.class)
public class PurchaseService {
    @Autowired
    private PurchaseDao purchaseDao;
    @Autowired
    private PurchaseMapper purchaseMapper;
    @Autowired
    private PurDetailDao purDetailDao;

    @Autowired
    private ProductService productService;
    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private UserDao userDao;
    private static final Map<String,String> map = new HashMap<>();

    static {
        map.put("purDate","pur_date");
        map.put("pdMoney", "pd_money");
    }
    /**
     * 添加采购单
     * @param purchaseEntity
     * @throws ServiceException
     */
    public Integer pur_insert(PurchaseEntity purchaseEntity)throws ServiceException{
        if(purchaseEntity.getPurId()!=null){//为修改
            if (purchaseEntity.getPurOk() != 0 && purchaseEntity.getPurOk()!=3)
                throw new ServiceException("采购单已经锁定");
        }
        try {
            if (purchaseEntity.getTbCustomerByCusId() != null && purchaseEntity.getTbCustomerByCusId().getCusId()!=null){}
            else
                purchaseEntity.setTbCustomerByCusId(null);
            if (purchaseEntity.getTbUserByUserId() != null && purchaseEntity.getTbUserByUserId().getUserId()!=null){}
            else
                purchaseEntity.setTbUserByUserId(null);
            if (purchaseEntity.getTbWarehouseByWhId() != null && purchaseEntity.getTbWarehouseByWhId().getWhId()!=null){}
            else
                purchaseEntity.setTbWarehouseByWhId(null);
            purchaseEntity.setPurOk(0);
            return purchaseDao.save(purchaseEntity).getPurId();
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("新建采购单失败");
        }
    }

    /**
     * 删除采购单
     * @param purId
     * @throws ServiceException
     */
    public boolean pur_logicDelete(int purId)throws ServiceException,NotFoundException {
        PurchaseEntity purchaseEntity=load(purId);
        if (purchaseEntity.getPurOk() != 0 && purchaseEntity.getPurOk()!=3)
            throw new ServiceException("采购单已经锁定");
        if(purchaseEntity==null){
            System.out.println("不存在该采购单");
            throw new NotFoundException("不存在该采购单");
        }
        try {
            purchaseEntity.setMagicDelete(1l);
            return purchaseDao.save(purchaseEntity)!=null;
        }catch (Exception e){
            e.printStackTrace();
            throw  new ServiceException("删除采购单");
        }
    }
    /**
     * 批量删除采购单
     * @param ids
     * @throws ServiceException
     */
    public boolean pur_logicDeleteAll(Long[] ids)throws ServiceException,NotFoundException {
        for (int i = 0; i < ids.length; i++) {
            pur_logicDelete(ids[i].intValue());
        }
        return true;
    }

    /**
     * 查询采购单
     * @return
     */
    public PageEntity<PurchaseVO> pur_findAll(Integer pageSize, Integer pageNumber) throws ServiceException{
        try {
            List<PurchaseEntity> rows =purchaseDao.findAllByMagicDeleteOrderByPurId(0l, new PageRequest(pageNumber,pageSize));
            int total=purchaseDao.pur_findAllCount();
            return new PageEntity<PurchaseVO>((long) total, getPurchaseVO(rows));
        }catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("查询所有采购单失败");
        }
    }

    /**
     * 高级查询
     * @param purchaseVO
     * @return
     * @throws ServiceException
     */
    public PageEntity<PurchaseEntity> findAllByManyConditions(PurchaseVO purchaseVO) {
        if(purchaseVO==null)
            return new PageEntity<>(0l, null);
        String order =purchaseVO.getPage().getSort(map);
        if(order.length()<=0)
            order = "pur_id desc";
        com.github.pagehelper.Page<MaintainOrderEntity> page1 = PageHelper.startPage(purchaseVO.getPage().getPage(), purchaseVO.getPage().getSize(), order+" nulls last");
        purchaseMapper.findByManyCondition(purchaseVO);
        return new PageEntity(page1.getTotal(), page1.getResult());
    }
    /**
     * 加载采购单
     * @param purId
     * @return
     * @throws ServiceException
     */
    public PurchaseVO load1(Integer purId) throws ServiceException{
        try {
            return getPurchaseVO1(purchaseDao.findAllByMagicDeleteAndPurId(0l, purId));
        }catch (Exception e){
            e.printStackTrace();;
            throw new ServiceException("加载采购单失败");
        }
    }
    /**
     * 加载采购单
     * @param purId
     * @return
     * @throws ServiceException
     */
    public PurchaseEntity load(Integer purId) throws NotFoundException{
            PurchaseEntity purchaseEntity = purchaseDao.findAllByMagicDeleteAndPurId(0l, purId);
            if(purchaseEntity==null)
                throw new NotFoundException("该采购单不存在");
        return purchaseEntity;
    }

    /**
     * 加载采购明细
     * @param id
     * @return
     */
    public List<PurchaseDetailVO> loadDeatil(Long id) {
        List<PurDetailEntity> purDetailEntities = purDetailDao.findAll(id.intValue());
        List<PurchaseDetailVO> purchaseDetailVOS = new ArrayList<>();
        for (PurDetailEntity purDetailEntity : purDetailEntities){
            int purId=0;
            int pfId=0;
            if(purDetailEntity.getTbPurchaseByPurId()!=null&&purDetailEntity.getTbPurchaseByPurId().getPurId()!=null){
                purId =purDetailEntity.getTbPurchaseByPurId().getPurId();
            }

            if(purDetailEntity.getTbProductFormatByPfId()!=null&&purDetailEntity.getTbProductFormatByPfId().getPfId()!=null){
               pfId=purDetailEntity.getTbProductFormatByPfId().getPfId();
            }
            int in = purchaseDao.inCount(purId,pfId );
            PurchaseDetailVO purchaseDetailVO = new PurchaseDetailVO(purDetailEntity,in);
            purchaseDetailVOS.add(purchaseDetailVO);
        }
        return purchaseDetailVOS;
    }
    /**
     * 修改采购明细
     * @param purDetailEntities
     * @return
     */
    public boolean addDetail(List<PurDetailEntity> purDetailEntities, Long id) throws NotFoundException, ServiceException {
        PurchaseEntity purchaseEntity = load(Math.toIntExact(id));
        if (purchaseEntity.getPurOk() != 0 && purchaseEntity.getPurOk()!=3)
            throw new ServiceException("采购单已经锁定");
        try {
            if(purDetailEntities!=null){
                buildDetails(purDetailEntities,purchaseEntity);
                purchaseDetailService.pd_insert1(purDetailEntities);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("修改采购明细失败");
        }
        return true;
    }
    /**
     * 建造采购明细（已经交付的产品会自动生成明细
     * @param purDetailEntities
     * @throws NotFoundException
     */
    private void buildDetails(List<PurDetailEntity> purDetailEntities, PurchaseEntity purchaseEntity) throws NotFoundException {
        if (purDetailEntities != null && purDetailEntities.size() > 0) {
            for (PurDetailEntity purDetailEntity : purDetailEntities) {
                ProductFormatEntity productFormatEntity = productService.load(purDetailEntity.getTbProductFormatByPfId().getPfId());
                purDetailEntity.setTbPurchaseByPurId(purchaseEntity);
                purDetailEntity.setTbProductFormatByPfId(productFormatEntity);
                purDetailEntity.setPdPrice(productFormatEntity.getPfPrice()==null?BigDecimal.valueOf(0):productFormatEntity.getPfPrice());
                purDetailEntity.setPdProfit(purDetailEntity.getPdTotal().subtract(productFormatEntity.getPfCost().multiply(BigDecimal.valueOf(purDetailEntity.getPdNum())))==null? BigDecimal.valueOf(0) :purDetailEntity.getPdTotal().subtract(productFormatEntity.getPfCost().multiply(BigDecimal.valueOf(purDetailEntity.getPdNum()))));
            }
        }
    }

    /**
     * 判断状态
     * @param
     * @return
     */
    public PurchaseEntity getState(Integer purId){
        List<PurchaseDetailVO> list = loadDeatil((long) purId);
        boolean a = true;
        boolean b = true;
        for (PurchaseDetailVO purchaseDetailVO1 : list) {
            if (purchaseDetailVO1.getPdWpNum() <= 0)//入库数量小于等于0，即未入库
                a = false;
            else b = false;
        }
        PurchaseEntity purchaseEntity= new PurchaseEntity();
        if (a == true)
            purchaseEntity.setPurState("入库完成");
        if (a == false && b == false)
            purchaseEntity.setPurState("部分入库");
        if (b == true)
            purchaseEntity.setPurState("新采购");
        return purchaseEntity;
    }
    private List<PurchaseVO> getPurchaseVO(List<PurchaseEntity> purchaseEntities){
        List<PurchaseVO> purchaseVOS=new ArrayList<>();
        for(PurchaseEntity purchaseEntity:purchaseEntities){
            purchaseVOS.add(new PurchaseVO(purchaseEntity));
        }
        return purchaseVOS;
    }
    private PurchaseVO getPurchaseVO1(PurchaseEntity purchaseEntity){
        PurchaseVO purchaseVO=new PurchaseVO(purchaseEntity);
        return purchaseVO;
    }
    //service
    public long countByUser(Long userId)throws ServiceException{
        try {
            return purchaseDao.countAllByTbUserByUserId(userDao.findUserByOne(0L,userId));
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("统计失败");
        }
    }
    public long countByMonth()throws ServiceException{
        try {
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH)+1;
            return purchaseDao.countAllByMonth(year, month);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("统计失败");
        }
    }
}
